<template>
  <div class="tui-input-number-container">
    <!-- 输入框容器 -->
    <div class="tui-input-number__wrap">
      <!-- 左侧减号按钮 -->
      <button v-if="controls" class="tui-input-number__button tui-input-number__decrease"
        :disabled="disabled || minDisabled" @click="decrease">
        <tui-icon icon="tui:minus" />
      </button>

      <!-- 输入框 -->
      <input ref="inputRef" :id="id" :name="name" type="number" :value="formattedValue" :placeholder="placeholder"
        :disabled="disabled" :readonly="readonly" :min="min" :max="max" :step="step" class="tui-input-number__input"
        :style="{ textAlign: align }" @focus="handleFocus" @blur="handleBlur" @input="handleInput"
        @change="handleChange" @keydown.up.prevent="increase" @keydown.down.prevent="decrease" />

      <!-- 右侧加号按钮 -->
      <button v-if="controls" class="tui-input-number__button tui-input-number__increase"
        :disabled="disabled || maxDisabled" @click="increase">
        <tui-icon icon="tui:plus" />
      </button>
    </div>

    <p v-if="errorMessage" class="tui-input-error">{{ errorMessage }}</p>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, watch, onMounted } from 'vue';
import type { TuiInputNumberProps } from './types';
import TuiIcon from '../icon/Icon.vue';

const props = withDefaults(defineProps<TuiInputNumberProps>(), {
  id: '',
  name: '',
  modelValue: null,
  min: -9007199254740991, // Number.MIN_SAFE_INTEGER的具体值
  max: 9007199254740991,  // Number.MAX_SAFE_INTEGER的具体值
  step: 1,
  stepStrictly: false,
  precision: undefined,
  size: 'default',
  disabled: false,
  controls: true,
  placeholder: '',
  readonly: false,
  errorMessage: '',
  align: 'center'
});

const emit = defineEmits<{
  (e: 'update:modelValue', value: number | null): void;
  (e: 'change', value: number | null): void;
  (e: 'focus', event: FocusEvent): void;
  (e: 'blur', event: FocusEvent): void;
}>();

const inputRef = ref<HTMLInputElement>();

// 格式化后的值
const formattedValue = computed(() => {
  if (props.modelValue === null || props.modelValue === undefined) {
    return '';
  }
  if (typeof props.precision === 'number') {
    return props.modelValue.toFixed(props.precision);
  }
  return props.modelValue;
});

// 最小禁用状态
const minDisabled = computed(() => {
  return props.modelValue !== null && props.modelValue <= props.min;
});

// 最大禁用状态
const maxDisabled = computed(() => {
  return props.modelValue !== null && props.modelValue >= props.max;
});

// 处理焦点事件
const handleFocus = (event: FocusEvent) => {
  emit('focus', event);
};

// 处理失焦事件
const handleBlur = (event: FocusEvent) => {
  emit('blur', event);
};

// 处理输入事件
const handleInput = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const value = target.value;

  // 如果值为空，设置为null
  if (value === '') {
    emit('update:modelValue', null);
    return;
  }

  // 转换为数字
  let numValue = parseFloat(value);

  // 如果不是数字，保持原值
  if (isNaN(numValue)) {
    target.value = formattedValue.value.toString();
    return;
  }

  // 应用精度
  if (typeof props.precision === 'number') {
    numValue = Number(numValue.toFixed(props.precision));
  }

  // 应用stepStrictly
  if (props.stepStrictly) {
    const step = props.step || 1;
    numValue = Math.round(numValue / step) * step;
  }

  // 限制范围
  numValue = Math.max(props.min, Math.min(props.max, numValue));

  emit('update:modelValue', numValue);
};

// 处理change事件
const handleChange = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const value = target.value;

  if (value === '') {
    emit('change', null);
  } else {
    const numValue = parseFloat(value);
    emit('change', isNaN(numValue) ? null : numValue);
  }
};

// 增加数值
const increase = () => {
  if (props.disabled || maxDisabled.value || props.readonly) {
    return;
  }

  const step = props.step || 1;
  let value = props.modelValue || 0;

  // 应用stepStrictly
  if (props.stepStrictly) {
    value = Math.round(value / step) * step + step;
  } else {
    value += step;
  }

  // 应用精度
  if (typeof props.precision === 'number') {
    value = Number(value.toFixed(props.precision));
  }

  // 限制最大值
  value = Math.min(props.max, value);

  emit('update:modelValue', value);
  emit('change', value);
};

// 减少数值
const decrease = () => {
  if (props.disabled || minDisabled.value || props.readonly) {
    return;
  }

  const step = props.step || 1;
  let value = props.modelValue || 0;

  // 应用stepStrictly
  if (props.stepStrictly) {
    value = Math.round(value / step) * step - step;
  } else {
    value -= step;
  }

  // 应用精度
  if (typeof props.precision === 'number') {
    value = Number(value.toFixed(props.precision));
  }

  // 限制最小值
  value = Math.max(props.min, value);

  emit('update:modelValue', value);
  emit('change', value);
};

// 监听外部值变化，更新输入框
watch(() => props.modelValue, (newValue) => {
  if (inputRef.value && newValue !== null && newValue !== undefined) {
    inputRef.value.value = formattedValue.value.toString();
  }
});

// 组件挂载后，初始化输入框值
onMounted(() => {
  if (inputRef.value && props.modelValue !== null && props.modelValue !== undefined) {
    inputRef.value.value = formattedValue.value.toString();
  }
});
</script>

<style lang="scss" scoped>
.tui-input-number-container {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;

  // 鼠标悬停效果
  &:not(:has(.tui-input-number__input:disabled)):hover {
    .tui-input-number__input {
      border-color: var(--tui-color-primary);
    }

    .tui-input-number__decrease {
      // 移除边框颜色变化，保持原有边框颜色
      background-color: rgba(0, 0, 0, 0.02); // 添加微弱背景色增强视觉效果
    }

    .tui-input-number__increase {
      // 移除边框颜色变化，保持原有边框颜色
      background-color: rgba(0, 0, 0, 0.02); // 添加微弱背景色增强视觉效果
    }
  }

  // 禁用状态
  &:has(.tui-input-number__input:disabled) {
    opacity: 0.6;
  }

  // 大号尺寸
  &.tui-input-number--large {
    .tui-input-number__wrap {
      height: 36px;
    }

    .tui-input-number__input {
      height: 100%;
      font-size: 16px;
      padding: 0 36px; // 为大号按钮留出空间
    }

    .tui-input-number__button {
      width: 36px;
    }
  }

  // 小号尺寸
  &.tui-input-number--small {
    .tui-input-number__wrap {
      height: 28px;
    }

    .tui-input-number__input {
      height: 100%;
      font-size: 12px;
      padding: 0 28px; // 为小号按钮留出空间
    }

    .tui-input-number__button {
      width: 28px;
    }
  }

  // 输入框容器
  .tui-input-number__wrap {
    position: relative;
    height: 32px; // 与按钮高度保持一致
    display: inline-block;

    // 输入框样式
    .tui-input-number__input {
      width: 100%;
      height: 100%;
      padding: 0 32px; // 为左右按钮留出空间
      border: 1px solid var(--tui-color-border);
      font-size: 14px;
      box-sizing: border-box;
      transition: border-color 0.3s;
      outline: none;
      background-color: var(--tui-color-bg-light);
      border-radius: 4px;

      // 聚焦效果
      &:focus {
        border-color: var(--tui-color-primary);
        box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
      }

      // 禁用状态
      &:disabled {
        background-color: var(--tui-color-bg-disabled);
        cursor: not-allowed;
        opacity: 0.6;
      }

      // 隐藏number输入框的上下箭头
      &::-webkit-inner-spin-button,
      &::-webkit-outer-spin-button {
        -webkit-appearance: none;
        margin: 0;
      }

      & {
        -moz-appearance: textfield;
      }
    }

    // 按钮基础样式
    .tui-input-number__button {
      width: 32px;
      height: 100%;
      padding: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      border: none; /* 移除边框，因为输入框已经有边框 */
      background-color: transparent;
      transition: all 0.3s; // 修改为all以包含所有过渡效果
      cursor: pointer;
      position: absolute;
      top: 0;
      z-index: 1; /* 确保按钮显示在输入框上方 */
      box-sizing: border-box;

      // 悬停效果
      &:hover:not(:disabled) {
        color: var(--tui-color-primary);
        background-color: rgba(0, 0, 0, 0.02); // 添加背景色确保整个区域有颜色
      }

      // 禁用状态
      &:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        color: var(--tui-color-text-disabled);
      }

      // 图标样式
      .tui-icon {
        width: 14px;
        height: 14px;
      }
    }

    // 左侧减号按钮样式
    .tui-input-number__decrease {
      left: 0;
      border-right: 1px solid var(--tui-color-border);
      // 为左侧按钮添加左上和左下圆角，与容器保持一致
      border-top-left-radius: inherit;
      border-bottom-left-radius: inherit;
      // 修复1像素间隙问题
      &:not(:disabled) {
        transition: all 0.3s;
      }
    }

    // 右侧加号按钮样式
    .tui-input-number__increase {
      right: 0;
      border-left: 1px solid var(--tui-color-border);
      // 为右侧按钮添加右上和右下圆角，与容器保持一致
      border-top-right-radius: inherit;
      border-bottom-right-radius: inherit;
      // 修复1像素间隙问题
      &:not(:disabled) {
        transition: all 0.3s;
      }
    }
  }

  // 错误信息样式
  .tui-input-error {
    color: var(--tui-color-danger);
    font-size: 12px;
    margin-top: 4px;
    margin-bottom: 0;
    position: absolute;
    bottom: -20px;
    left: 0;
  }
}
</style>